package org.hackystat.devcathlon.team;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.hackystat.devcathlon.user.User;

/**
 * A thread-safe singleton class that manages access to the Teams in this system. 
 * @author Philip Johnson
 */
public class TeamManager {
  /** The singleton instance of this class. */
  private static TeamManager theInstance = new TeamManager();
  /** The (team name, team instance) tuples. */
  private Map<String, Team> names2teams = new HashMap<String, Team>();
  /** The private constructor. */
  private TeamManager() {
    // does nothing at this point; will initialize from database later.
  }

  /**
   * Returns the singleton instance of the TeamManager.
   * @return The TeamManager.
   */
  public static TeamManager getInstance() {
    return TeamManager.theInstance;
  }

  /**
   * Adds a new team to the system. 
   * @param name The name of the new team. Must be unique.
   * @param owner The user who owns this team.  
   * @param users The set of Users on this team. 
   * @return The new team instance. 
   * @throws TeamException If the team name is not unique. 
   */
  public synchronized Team addTeam(String name, User owner, Set<User> users) throws TeamException {
    if (this.names2teams.containsKey(name)) {
      throw new TeamException("Attempt to add team with duplicate name: " + name);
    }
    Team team = new Team(name, owner, users);
    this.names2teams.put(name, team);
    return team;
  }
  
  /**
   * Returns the Team instance associated with the name, or null if not found. 
   * @param name The name of the team to be retrieved. 
   * @return The Team instance, or null if not found. 
   */
  public synchronized Team getTeam (String name) {
    return this.names2teams.get(name);
  }
  
  /**
   * Removes the specified team from the map of teams.
   * Does nothing if the team is not in the map.
   * @param name The name of the team to remove. 
   */
  public synchronized void deleteTeam(String name) {
    this.names2teams.remove(name);
  }
  
}
